#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "handle.h"

int main(){
    // 声明socket存放地址
    struct sockaddr_in ser_addr;
    struct sockaddr_in cli_addr;

    memset(&ser_addr, 0, sizeof(ser_addr));
    memset(&cli_addr, 0, sizeof(cli_addr));

    // 声明套接字，socket函数产生一个套接字描述符
    int ser_socket = socket(AF_INET, SOCK_STREAM, 0); // ipv4, 双向字节流
    if(ser_socket == -1) {
        printf("Create Socket Error!");
        return -1;
    }
    printf("Create Socket OK!\n");

    // 设置ser_addr
    ser_addr.sin_family = AF_INET;//设置tcp协议
    ser_addr.sin_addr.s_addr = inet_addr("10.0.0.1"); // 设置具体的ip地址
    ser_addr.sin_port = htons(80);//设置端口
    //todo : 两个线程分别监听 80 和 443

    // 绑定，让套接字文件在通信时使用固定的IP和端口号，描述符和地址绑定
    if(bind(ser_socket, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) == -1) {
        printf("Bind Error!\n");
        close(ser_socket);
        return -1;
    }
    printf("Server Bind OK!\n");

    // 监听，将套接字文件描述符从主动转为被动文件描述符，然后用于被动监听客户端的连接
    if(listen(ser_socket, 20) == -1) {
        printf("Listen Error!\n");
        close(ser_socket);
        return -1;
    }
    printf("Server starts to Listen!\n\n");

    // 建立具体连接
    while(1) {
        int nsize = sizeof(cli_addr); // addr地址长度
        int new_socket = accept(ser_socket, (struct sockaddr*)&cli_addr, &nsize);
        //accept被动监听客户端发起的tcp连接请求，三次握手后连接建立成功。连接成功后会记录客端的ip和端口
        printf("New client connection request arrived and new session created!\n\n");
        int rc = req_handle(new_socket); //交给一个线程处理？
        if(rc != 0) {
            printf("Request handle Error!\n");
        }

        close(new_socket);
    }

    close(ser_socket);

    return 0;
}


